對於資源訪問與資源引用路徑沒弄清楚真的會有點混亂,希望透過這一天的梳理在未來就不會再有困惑了
index.html內容
<img src="static/imag/tomcat.png">
內容
<img src="../../../static/imag/tomcat.png">
protected.html內容
<img src="../../static/imag/tomcat.png">
AccessProtectedResourceServlet
@WebServlet("/AccessProtectResourceServlet")
public class AccessProtectResourceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("WEB-INF/views/protected.html").forward(req, resp);
}
}
你會發現他發送兩次請求,第一次訪問index.html,第二次取得圖片時相對路徑會依照第一次訪問資源路徑去取得圖片
tomcat.png相對於test.html的路徑為:../../../static/imag/tomcat.png
前一日有提到在WEB-INF下的頁面是受保護資源,需要透過Servlet請求轉法才能看到。此處如果以資料夾結構的思維可能會認為tomcat.png相對於protected.html的路徑而設置為../../static/imag/tomcat.png,而得到下面錯誤訊息
正確來看應
以固定的路徑作為出發點尋找目標資源,不會依賴當前訪問資源路徑
<img src="/static/imag/tomcat.png">
缺點:目標資源會受當前資源路徑影響,不同的位置相對路徑寫法就不同
優點:絕對路徑寫法一致
缺點:絕對路徑需要寫網站上下文(本例是MyWebApp),若有異動則需要將所有訪問資源絕對路徑進行修改。html有base標籤可以簡化這個部分,訪問資源時會幫你將頁面中每一個路徑加上/MyWebApp/變成/MyWebApp/static/imag/tomcat.png
<head>
<base href="/MyWebApp/"/>
</head>
<img src="static/imag/tomcat.png">
<img src="static/imag/tomcat.png">
ServletA
@WebServlet("/x/y/z/ServletA")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("訪問ServletA");
resp.sendRedirect("ServletB");
}
}
ServletB
@WebServlet("/ServletB")
public class ServletB extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res){
System.out.println("訪問ServletB");
}
}
@WebServlet("/x/y/z/ServletA")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("訪問ServletA");
//絕對路徑
resp.sendRedirect("/MyWebApp/ServletB");
}
}
請求轉發為Server端行為所以client端不會知道,網址不變
@WebServlet("/x/y/z/ServletA")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("訪問ServletA");
req.getRequestDispatcher("../../../ServletB").forward(req,resp);
}
}
絕對路徑不需要添加網站上下文(MyWebApp)
@WebServlet("/x/y/z/ServletA")
public class ServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("訪問ServletA");
req.getRequestDispatcher("/ServletB").forward(req,resp);
}
}
絕對路徑以/開頭,相對路徑相對於當前訪問資源,所以以當前訪問資源路徑為起始點。比較特別的是請求轉發的絕對路徑是不需要添加網站上下文(MyWebApp),故請求轉發的/代表的是http://localhost/MyWebApp/。
是不是有被路徑問題繞得暈頭轉向了呢,問題就在於有網站上下文這個問題,所以把網站上下文設定為/並且資源路徑設為絕對路徑的方式是比較好的實踐方式,網站上下文的目的是為了區分在Application Server上有多個項目佈署,但實際上我們的Application Server只會掛載一個Web項目,未來的範例專案我們都會省去MyWebApp喔